<template>
  <div class="color-picker-container">
    <div 
      class="color-preview" 
      :style="{ backgroundColor: innerValue }"
      @click="showPicker = !showPicker"
    ></div>
    <a-input 
      :value="innerValue"
      @update:value="updateValue"
      class="color-input" 
      @click="showPicker = !showPicker"
    />
    <div v-if="showPicker" class="color-picker-dropdown">
      <div class="picker-header">
        <span>选择颜色</span>
        <a-button type="text" size="small" @click="showPicker = false">
          <template #icon><close-outlined /></template>
        </a-button>
      </div>
      <div class="color-grid">
        <div 
          v-for="color in presetColors" 
          :key="color" 
          class="color-grid-item"
          :style="{ backgroundColor: color }"
          @click="selectColor(color)"
        ></div>
      </div>
      <div class="picker-footer">
        <a-input 
          :value="innerValue"
          @update:value="updateValue"
          placeholder="#RRGGBB"
        />
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, defineProps, defineEmits, watch, computed } from 'vue';
import { CloseOutlined } from '@ant-design/icons-vue';

const props = defineProps({
  modelValue: {
    type: String,
    default: '#1890ff'
  }
});

const emit = defineEmits(['update:modelValue']);
const showPicker = ref(false);

// 使用计算属性处理双向绑定
const innerValue = computed({
  get: () => props.modelValue,
  set: (value) => {
    emit('update:modelValue', value);
  }
});

// 预设颜色
const presetColors = [
  '#1890ff', '#f5222d', '#fa8c16', '#faad14', '#52c41a', 
  '#13c2c2', '#722ed1', '#eb2f96', '#000000', '#333333', 
  '#666666', '#999999', '#cccccc', '#ffffff', '#f5f5f5'
];

// 选择颜色
const selectColor = (color: string) => {
  innerValue.value = color;
  showPicker.value = false;
};

// 更新颜色
const updateValue = (value: string) => {
  innerValue.value = value;
};

// 点击外部关闭颜色选择器
const handleClickOutside = (event: MouseEvent) => {
  const target = event.target as HTMLElement;
  if (!target.closest('.color-picker-container')) {
    showPicker.value = false;
  }
};

// 挂载事件监听
watch(showPicker, (val) => {
  if (val) {
    setTimeout(() => {
      document.addEventListener('click', handleClickOutside);
    }, 0);
  } else {
    document.removeEventListener('click', handleClickOutside);
  }
});
</script>

<style scoped>
.color-picker-container {
  display: flex;
  align-items: center;
  position: relative;
  width: 100%;
}

.color-preview {
  width: 20px;
  height: 20px;
  border-radius: 4px;
  margin-right: 8px;
  border: 1px solid #d9d9d9;
  cursor: pointer;
}

.color-input {
  flex: 1;
  cursor: pointer;
}

.color-picker-dropdown {
  position: absolute;
  top: 100%;
  left: 0;
  width: 220px;
  background: white;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  z-index: 1000;
  margin-top: 4px;
  padding: 10px;
}

.picker-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}

.color-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 8px;
  margin-bottom: 10px;
}

.color-grid-item {
  width: 100%;
  height: 24px;
  border-radius: 4px;
  border: 1px solid #f0f0f0;
  cursor: pointer;
  transition: transform 0.2s;
}

.color-grid-item:hover {
  transform: scale(1.1);
}

.picker-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
</style> 